package algo;

import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.AssertJUnit;
import static org.testng.AssertJUnit.assertTrue;
import java.util.ArrayList;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;

public class RockPaperScissorsTest {
	RockPaperScissors rps;
	ArrayList <RPSEnum> maliste1;
	ArrayList <RPSEnum> maliste2;
	Player p1;
	Player p2;
	
	@BeforeClass //classe faite, les coups sont déjà positionnés à l’avance nous connaisons d’or et déjà le résultat
	public void SetUpClass()
	{
		rps=new RockPaperScissors();
		maliste1=new ArrayList <RPSEnum> ();
		maliste2=new ArrayList <RPSEnum> ();
		
		maliste1.add(RPSEnum.ROCK);
		maliste1.add(RPSEnum.PAPER);
		maliste1.add(RPSEnum.SCISSOR);
		
		maliste2.add(RPSEnum.SCISSOR);
		maliste2.add(RPSEnum.PAPER);
		maliste2.add(RPSEnum.ROCK);
		
		p1=new Player("Bobby",maliste1);
		p2=new Player("Paul",maliste2);
		//Set the collection of moves for each player in the initializing method
	}
	@BeforeClass //Les coups sont mis en place grace à une function random, le r”sultat n’est pas connu à l’avance
	public void SetUpClassRandom()
	{
	
	 
		
		Player p1= new Player ("Bob");
		Player p2= new Player("Pol");

		

			
		//Set the collection of moves for each player in the initializing method
	}
	@AfterClass//a la fin de l’exécution des classes on nettoie tout
	public void TearDownClass()
	{
		rps=null;
		maliste1.clear();
		maliste2.clear();
		p1.clearPlayer();
		p2.clearPlayer();
		//Ensure your release resources 
	}


 /* @Test
	void testWinPlay()
	{
	  //throw new RuntimeException("Test not implemented");
	Result rs=rps.play(RPSEnum.PAPER, RPSEnum.ROCK);
	assert(rs.equals(Result.WIN)); //le test va echouer ds l'��tape 1 //etape 2 on a mis ds play WIN donc passed

	}
  @Test 
  void testTiePlay()
  {
	  Result rs=rps.play(RPSEnum.PAPER, RPSEnum.ROCK);
		assert(rs.equals(Result.TIE)); //etape 1 vu que pas
de condition ds play et resultat=win retourne faux
//etape 2 on passe a tie ds la fct play et ça marche ms win play ne
marche plus
	  
  }
  
  @Test
  void testLostPlay()
  {
	  Result rs=rps.play(RPSEnum.PAPER, RPSEnum.ROCK);
		assert(rs.equals(Result.LOST));//etape 1 vu que pas
de condition ds play et resultat=win retourne faux
// etape 2 on
passe a lost ds la fct play et ça marche ms win play ne marche plus
  }
  */
	
	//retourne win si on est dans cette situation rock/ scissor ou scissor/ paper...
  @DataProvider (name="win")
  public Object[][] createWinData()
  {return new Object[][]
		  {
	  {RPSEnum.ROCK,RPSEnum.SCISSOR},
	  {RPSEnum.SCISSOR,RPSEnum.PAPER},
	  {RPSEnum.PAPER,RPSEnum.ROCK},
		  };
  }
//retourne tie si on est dans cette situation rock/rock ou scissor/scissor...
  
  @DataProvider (name="tie")
public Object[][] createTieData()
  {
	  return new Object[][]
			  {
		  {RPSEnum.ROCK,RPSEnum.ROCK},
		  {RPSEnum.SCISSOR,RPSEnum.SCISSOR},
		  {RPSEnum.PAPER,RPSEnum.PAPER},
			  };
	  
  }
//retourne lost si on est dans cette situation scissor/rock ou paper/scissor...
  @DataProvider (name="lost")
 public Object[][] createLostData() 
  {
	  return new Object[][]
			  {
		  {RPSEnum.SCISSOR,RPSEnum.ROCK},
		  {RPSEnum.PAPER,RPSEnum.SCISSOR},
		  {RPSEnum.ROCK,RPSEnum.PAPER},
			  };
  }
  
  /*Les 3 tests suivants ne peuvent pas marcher simultanément 
   * soit le joueur 1 gagne,est à égalité ou perd.
   *  Ces 3 tests nous permettent 
   * de voir que le random ne donne pas toujours le meme résultat.*/
  @Test
  public void TestWinPlay()
  {
	  Result rs=rps.play(p1, p2);
	 assertTrue(p1.getResult()==2);
  }
  
  @Test
  public void TestTiePlay()
  {
	  Result rs=rps.play(p1, p2);
	 assertTrue(p1.getResult()==1);
  }
  
  @Test
  public void TestLosePlay()
  {
	  Result rs=rps.play(p1, p2);
	 assertTrue(p1.getResult()==0);
  }
 


/**test verifiant que les 2 scores sont inf à 11, marche tout le temps
* */
  @Test
  public void TestSeparateScoreInf()
  { 
	  Result rs=rps.play(p1, p2);
	  assertTrue(p1.getScore()<=11);  
	  assertTrue(p2.getScore()<=11);  
	  
  }
  /**test vérifie que score1+score2<20, marche tout le temps *
  */
  @Test
  public void TestTotalScoreInf()
  { Result rs=rps.play(p1, p2);
  assertTrue((p1.getScore()+p2.getScore())<=20); 
	
  }
  /**Ce test enumeration vérifie que les 3 rpsenum sont compris dans la liste aléatoire, il peut fail mais c’est assez rare car les probabilities ne jouent pas en cette faveur
  * */
  @Test
  public void TestTypeEnum()
  {   
	  Result rs=rps.play(p1, p2);
	  ArrayList <RPSEnum> array=p1.getListdecoups();
	  boolean number1=array.contains(RPSEnum.ROCK);
	  boolean number2=array.contains(RPSEnum.PAPER);
	  boolean number3=array.contains(RPSEnum.SCISSOR);
	 
	  assertTrue(number1);
	  assertTrue(number2);
	  assertTrue(number3);
	 
	
  }
  
  
  
  
  
  @Test(dataProvider = "win")  // si on change ac tie ou lost ��a donne d'autres donn��es et ��a fail
  public void Test2WinPlay(RPSEnum p1,RPSEnum p2)
  {
	  Result rs=rps.play(p1, p2);
	  assert(rs.equals(Result.WIN));
  }
  
  @Test(dataProvider = "tie")// si on change ac win ou lost ��a donne d'autres donn��es et ��a fail
  public void Test2TiePlay(RPSEnum p1,RPSEnum p2)
  { 
	  Result rs=rps.play(p1, p2);
  assert(rs.equals(Result.TIE));
  }

  @Test(dataProvider = "lost")// si on change ac tie ou win ��a donne d'autres donn��es et ��a fail
  public void Test2LostPlay(RPSEnum p1,RPSEnum p2)
  { 
	Result rs=rps.play(p1, p2);
  assert(rs.equals(Result.LOST));
  }
  
  

}
